<!DOCTYPE html>
<html>
<head>
    <title>Circle container demo - p2.js physics engine</title>
    <script src="../build/p2.js"></script>
    <script src="../build/p2.renderer.js"></script>
    <link href="css/demo.css" rel="stylesheet"/>
    <meta name="description" content="A simple container made out of planes, filled with a lot of circles. Stress tests the contact+friction solver.">
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
</head>
<body>
    <script>

        var enablePositionNoise = true, // Add some noise in circle positions
            N = 15,         // Number of circles in x direction
            M = 15,         // and in y
            r = 0.07,       // circle radius
            d = 2.2;        // Distance between circle centers

        // Create demo application
        var app = new p2.WebGLRenderer(function(){

            // Create the world
            var world = new p2.World({
                gravity : [0,-5]
            });

            // Pre-fill object pools. Completely optional but good for performance!
            world.overlapKeeper.recordPool.resize(16);
            world.narrowphase.contactEquationPool.resize(1024);
            world.narrowphase.frictionEquationPool.resize(1024);

            this.setWorld(world);

            // Set stiffness of all contacts and constraints
            world.setGlobalStiffness(1e8);

            // Max number of solver iterations to do
            world.solver.iterations = 20;

            // Solver error tolerance
            world.solver.tolerance = 0.02;

            // Enables sleeping of bodies
            world.sleepMode = p2.World.BODY_SLEEPING;

            // Create circle bodies
            for(var i=0; i<N; i++){
                for(var j=M-1; j>=0; j--){
                    var x = (i-N/2)*r*d+(enablePositionNoise ? Math.random()*r : 0);
                    var y = (j-M/2)*r*d;
                    var p = new p2.Body({
                        mass: 1,
                        position: [x, y],
                    });
                    p.addShape(new p2.Circle({ radius: r }));
                    p.allowSleep = true;
                    p.sleepSpeedLimit = 1;  // Body will feel sleepy if speed<1 (speed is the norm of velocity)
                    p.sleepTimeLimit = 1;   // Body falls asleep after 1s of sleepiness
                    world.addBody(p);
                }
            }

            // Compute max/min positions of circles
            var xmin = (-N/2 * r*d),
                xmax = ( N/2 * r*d),
                ymin = (-M/2 * r*d),
                ymax = ( M/2 * r*d);

            // Create bottom plane
            var plane = new p2.Body({
                position : [0,ymin],
            });
            plane.addShape(new p2.Plane());
            world.addBody(plane);

            // Left plane
            var planeLeft = new p2.Body({
                angle: -Math.PI/2,
                position: [xmin, 0]
            });
            planeLeft.addShape(new p2.Plane());
            world.addBody(planeLeft);

            // Right plane
            var planeRight = new p2.Body({
                angle: Math.PI/2,
                position: [xmax, 0]
            });
            planeRight.addShape(new p2.Plane());
            world.addBody(planeRight);

            // Start demo
            this.frame(0, 0, 4, 4);
        });

    </script>
</body>
</html>
